package com.sheng.leetcode.year2025.month09.day19;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author by ls
 * @date 2025/9/19
 * <p>
 * 3484. 设计电子表格<p>
 * <p>
 * 电子表格是一个网格，它有 26 列（从 'A' 到 'Z'）和指定数量的 rows。每个单元格可以存储一个 0 到 105 之间的整数值。<p>
 * 请你实现一个 Spreadsheet 类：<p>
 * Spreadsheet(int rows) 初始化一个具有 26 列（从 'A' 到 'Z'）和指定行数的电子表格。所有单元格最初的值都为 0 。<p>
 * void setCell(String cell, int value) 设置指定单元格的值。单元格引用以 "AX" 的格式提供（例如，"A1"，"B10"），其中字母表示列（从 'A' 到 'Z'），数字表示从 1 开始的行号。<p>
 * void resetCell(String cell) 重置指定单元格的值为 0 。<p>
 * int getValue(String formula) 计算一个公式的值，格式为 "=X+Y"，其中 X 和 Y 要么 是单元格引用，要么非负整数，返回计算的和。<p>
 * 注意： 如果 getValue 引用一个未通过 setCell 明确设置的单元格，则该单元格的值默认为 0 。<p>
 * <p>
 * 示例 1：<p>
 * 输入：<p>
 * ["Spreadsheet", "getValue", "setCell", "getValue", "setCell", "getValue", "resetCell", "getValue"]<p>
 * [[3], ["=5+7"], ["A1", 10], ["=A1+6"], ["B2", 15], ["=A1+B2"], ["A1"], ["=A1+B2"]]<p>
 * 输出：<p>
 * [null, 12, null, 16, null, 25, null, 15]<p>
 * 解释<p>
 * Spreadsheet spreadsheet = new Spreadsheet(3); // 初始化一个具有 3 行和 26 列的电子表格<p>
 * spreadsheet.getValue("=5+7"); // 返回 12 (5+7)<p>
 * spreadsheet.setCell("A1", 10); // 设置 A1 为 10<p>
 * spreadsheet.getValue("=A1+6"); // 返回 16 (10+6)<p>
 * spreadsheet.setCell("B2", 15); // 设置 B2 为 15<p>
 * spreadsheet.getValue("=A1+B2"); // 返回 25 (10+15)<p>
 * spreadsheet.resetCell("A1"); // 重置 A1 为 0<p>
 * spreadsheet.getValue("=A1+B2"); // 返回 15 (0+15)<p>
 * <p>
 * 提示：<p>
 * 1 <= rows <= 10^3<p>
 * 0 <= value <= 10^5<p>
 * 公式保证采用 "=X+Y" 格式，其中 X 和 Y 要么是有效的单元格引用，要么是小于等于 10^5 的 非负 整数。<p>
 * 每个单元格引用由一个大写字母 'A' 到 'Z' 和一个介于 1 和 rows 之间的行号组成。<p>
 * 总共 最多会对 setCell、resetCell 和 getValue 调用 10^4 次。<p>
 */
public class LeetCode3484 {

    @Test
    public void test() {
        // 初始化一个具有 3 行和 26 列的电子表格
        Spreadsheet spreadsheet = new Spreadsheet(3);
        // 返回 12 (5+7)
        System.out.println(spreadsheet.getValue("=5+7"));
        // 设置 A1 为 10
        spreadsheet.setCell("A1", 10);
        // 返回 16 (10+6)
        System.out.println(spreadsheet.getValue("=A1+6"));
        // 设置 B2 为 15
        spreadsheet.setCell("B2", 15);
        // 返回 25 (10+15)
        System.out.println(spreadsheet.getValue("=A1+B2"));
        // 重置 A1 为 0
        spreadsheet.resetCell("A1");
        // 返回 15 (0+15)
        System.out.println(spreadsheet.getValue("=A1+B2"));

//        Spreadsheet spreadsheet = new Spreadsheet(458);
//        System.out.println(spreadsheet.getValue("=0126+10272"));
    }
}

class Spreadsheet {

    private Map<String, Integer> map;

    /**
     * 初始化一个具有 26 列（从 'A' 到 'Z'）和指定行数的电子表格。所有单元格最初的值都为 0 。
     *
     * @param rows 行数
     */
    public Spreadsheet(int rows) {
        // 初始化
        map = new HashMap<>();
    }

    /**
     * 设置指定单元格的值。单元格引用以 "AX" 的格式提供（例如，"A1"，"B10"），其中字母表示列（从 'A' 到 'Z'），数字表示从 1 开始的行号。
     *
     * @param cell  单元格
     * @param value 值
     */
    public void setCell(String cell, int value) {
        map.put(cell, value);
    }

    /**
     * 重置指定单元格的值为 0 。
     *
     * @param cell 单元格
     */
    public void resetCell(String cell) {
        map.put(cell, 0);
    }

    /**
     * 计算一个公式的值，格式为 "=X+Y"，其中 X 和 Y 要么 是单元格引用，要么非负整数，返回计算的和。
     * 注意： 如果 getValue 引用一个未通过 setCell 明确设置的单元格，则该单元格的值默认为 0 。
     *
     * @param formula 计算公式
     * @return 值
     */
    public int getValue(String formula) {
        // 使用正则表达式匹配“=X+Y”结构
        Pattern pattern = Pattern.compile("=([A-Z0-9]+)\\+([A-Z0-9]+)");
        Matcher matcher = pattern.matcher(formula);

        if (matcher.matches()) {
            // 提取 X 和 y
            String x = matcher.group(1);
            String y = matcher.group(2);

            // 校验 X 是否是纯数字
            int xNum, yNum;
            if (x.matches("\\d+")) {
                xNum = Integer.parseInt(x);
            } else {
                xNum = map.getOrDefault(x, 0);
            }

            // 校验 Y 是否是纯数字
            if (y.matches("\\d+")) {
                yNum = Integer.parseInt(y);
            } else {
                yNum = map.getOrDefault(y, 0);
            }
            return xNum + yNum;

        }
        return -1;
    }
}

/*
  Your Spreadsheet object will be instantiated and called as such:
  Spreadsheet obj = new Spreadsheet(rows);
  obj.setCell(cell,value);
  obj.resetCell(cell);
  int param_3 = obj.getValue(formula);
 */
